package main

import (
	//"log"
	consulapi "github.com/hashicorp/consul/api"
	json "github.com/json-iterator/go"
)

/*Subj 服务器订阅消息的格式为：服务类型.子服务.消息类型.服务实例
*1. game.ddz.event.1cm0
*2. info.ginfo.event.me
*3. gate.ws.queue.2if
 */
type SrvInsData struct {
	SrvID      string `json:"SrvID"`
	SubSrvID   string `json:"SubSrvID"`
	InstanceId string `json:"InstanceId"`
	EventSubj  string `json:"EventSubj"`
	ReqSubj    string `json:"ReqSubj"`
	QueueSubj  string `json:"QueueSubj"`
	QueueName  string `json:"QueueName"`
	//表示当前服务实例是什么状态：可以用在服务无缝切换或其他多状态时使用
	Status string `json:"Status"`
}

func (this *SrvInsData) Copy() *SrvInsData {
	data := new(SrvInsData)

	data.SrvID = this.SrvID
	data.SubSrvID = this.SubSrvID
	data.InstanceId = this.InstanceId

	data.EventSubj = this.EventSubj
	data.ReqSubj = this.ReqSubj
	data.QueueSubj = this.QueueSubj
	data.QueueName = this.QueueName
	data.Status = this.Status

	return data
}

type RegClientInfo struct {
	Addr    string
	CConf   *consulapi.Config
	CClient *consulapi.Client
}

func NewRegClient(addr string) *RegClientInfo {
	regClient := new(RegClientInfo)
	err := regClient.Init(addr)
	if err != nil {
		return nil
	}
	return regClient
}

func (this *RegClientInfo) Init(addr string) error {
	this.Addr = addr
	this.CConf = consulapi.DefaultConfig()
	this.CConf.Address = this.Addr
	var err error
	this.CClient, err = consulapi.NewClient(this.CConf)
	return err
}

func (this *RegClientInfo) GetServiceData() ([]SrvInsData, error) {

	//client.Health()
	var services map[string]*consulapi.AgentService
	var err error

	services, err = this.CClient.Agent().Services()

	if nil != err {
		//log.Println("in consual list Services:", err)
		return nil, err
	}
	var tmData SrvInsData
	data := make([]SrvInsData, 0)

	for _, val := range services {

		if len(val.Tags) > 0 {
			strKV := val.Tags[0]
			err = json.Unmarshal([]byte(strKV), &tmData)
			data = append(data, tmData)
		}

	}
	return data, nil
}

func (this *RegClientInfo) GetAllKVData() ([]string, error) {

	//data := make([]*SrvInsData, 0)
	data, _, err := this.CClient.KV().Keys("", "", nil)
	return data, err

}

func (this *RegClientInfo) PutKVData(key string, val []byte) (bool, error) {

	kvp := &consulapi.KVPair{Key: key, Value: val}

	_, err := this.CClient.KV().Put(kvp, nil)
	//ok, _, err := this.CClient.KV().Acquire(kvp, nil)
	return true, err

}

func (this *RegClientInfo) GetKVData(key string) ([]byte, error) {

	kvp, _, err := this.CClient.KV().Get(key, nil)
	return kvp.Value, err

}

func (this *RegClientInfo) RemoveKVData(key string) error {

	_, err := this.CClient.KV().Delete(key, nil)
	return err

}
